//
// SoapTrace.Net - A soap message monitoring utility. 
//
// Copyright (C) 2004 Matthew Ward
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Matthew Ward (mrward@users.sourceforge.net)

using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;

namespace SoapTrace.Core.Diagnostics
{
	/// <summary>
	/// Represents the method that will handle the 
	/// <see cref="Logger.LogEntryAdded"/> event.
	/// </summary>
	public delegate void LogEventHandler( object sender, LogEventArgs e );
	
	/// <summary>
	/// Core diagnostic trace logger for the Soap Trace Application.
	/// </summary>
	public sealed class Logger
	{
		/// <summary>
		/// Occurs when <see cref="Logger.Log"/>, <see cref="Logger.LogError"/>,
		/// <see cref="Logger.LogError"/>, <see cref="Logger.LogWarning"/> or
		/// <see cref="Logger.LogDebug"/> methods are called.
		/// </summary>
		public static event LogEventHandler LogEntryAdded;
		
		/// <summary>
		/// The <see cref="Logger"/> instance.
		/// </summary>
		private static Logger m_Logger;
		
		/// <summary>
		/// The log level.
		/// </summary>
		private static LogLevel m_LogLevel = LogLevel.Info;
		
		/// <summary>
		/// Logs bytes as string.
		/// </summary>
		private static bool m_LogBytesAsString = true;
		
		/// <summary>
		/// Creates a new instance of the <see cref="Logger"/> class.
		/// </summary>
		private Logger( )
		{
		}
			
		/// <summary>
		/// Gets or sets the log level.
		/// </summary>
		public static LogLevel Level
		{
			get
			{
				return m_LogLevel;
			}
			
			set
			{
				m_LogLevel = value;
			}
		}

		/// <summary>
		/// Gets or sets whether to log bytes as strings or bytes.
		/// </summary>
		public static bool LogBytesAsString
		{
			get
			{
				return m_LogBytesAsString;
			}
			
			set
			{
				m_LogBytesAsString = value;
			}
		}
		
		/// <summary>
		/// Logs an informational message.
		/// </summary>
		/// <param name="message">The message to log.</param>
		public static void Log( string message )
		{
			AddEntry( LogLevel.Info, message );
		}
		
		/// <summary>
		/// Logs an error message.
		/// </summary>
		/// <param name="message">The message to log.</param>
		public static void LogError( string message )
		{
			AddEntry( LogLevel.Error, message );
		}		
		
		/// <summary>
		/// Logs a warning message.
		/// </summary>
		/// <param name="message">The message to log.</param>
		public static void LogWarning( string message )
		{
			AddEntry( LogLevel.Warn, message );
		}
		
		/// <summary>
		/// Logs a debug message.
		/// </summary>
		/// <param name="message">The message to log.</param>
		public static void LogDebug( string message )
		{
			AddEntry( LogLevel.Debug, message );
		}
		
		/// <summary>
		/// Gets whether the log level is enabled.
		/// </summary>
		public static bool IsLevelEnabled( LogLevel level )
		{
			bool IsLogLevelEnabled = false;
			
			if( ( int )m_LogLevel >= ( int )level )
			{
				IsLogLevelEnabled = true;
			}
			
			return IsLogLevelEnabled;
		}
		
		/// <summary>
		/// Adds a <see cref="LogEntry"/>.
		/// </summary>
		/// <param name="level">A <see cref="LogLevel"/>.</param>
		/// <param name="message">The log message.</param>
		private static void AddEntry( LogLevel level, string message )
		{
			if( ( int )level >= ( int )m_LogLevel )
			{
				LogEntry Entry = new LogEntry( message, level );
			
				OnLogEntryAdded( Entry );
			}
		}
		
		/// <summary>
		/// Raises the <see cref="LogEntryAdded"/> event.
		/// </summary>
		/// <param name="entry">The <see cref="LogEntry"/> associated with
		/// the event.</param>
		private static void OnLogEntryAdded( LogEntry entry )
		{
			if( LogEntryAdded != null )
			{
				LogEventArgs LogEventArgs = new LogEventArgs( entry );
				
				LogEntryAdded( GetInstance( ), LogEventArgs );
			}
		}
		
		/// <summary>
		/// Gets the <see cref="Logger"/> singleton.
		/// </summary>
		/// <returns>A reference to the <see cref="Logger"/> singleton.</returns>
		private static Logger GetInstance( )
		{
			if( m_Logger != null )
			{
				m_Logger = new Logger( );
			}
			
			return m_Logger;
		}
		
//		private static string GetMethodInfo( )
//		{
//			StackTrace StackTrace = new StackTrace( );
//			
//			string MethodInfo = String.Empty;
//			
//			for( int i = 0; i < StackTrace.FrameCount; ++i )
//			{
//				StackFrame Frame = StackTrace.GetFrame( i );
//				MethodBase MethodBase = Frame.GetMethod( );
//				Type DeclaringType = MethodBase.DeclaringType;
//				
//				MethodInfo += DeclaringType.Name + "." + MethodBase.Name + "\r\n";
//			}
//			
//			return MethodInfo;
//		}
	}
}
